/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
$$$                                                                    $$$
$$$  MODULO:    general.c                                              $$$
$$$                                                                    $$$
$$$  FUNCIONES: usrGrabarLog                                           $$$
$$$             usrEliminaFinDeLinea                                   $$$
$$$             usrValidarConfig									   $$$	
$$$				usrBorrarBuffer										   $$$	
$$$				usrLevantoConfiguracion								   $$$
$$$																	   $$$	
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
$$$                                                                    $$$
$$$   DESCRIPCION: Este modulo contiene funciones orientadas a la      $$$
$$$                reutilizacion.									   $$$
$$$																	   $$$
$$$                                                                    $$$
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
*/

# include "libsys.h"
# include "constantes.h"
# include "estructuras.h"
# include "globales.h"

void usrGrabarLog ( char* cTipo, const char * cvDetalle, HANDLE hFile,int iIdHilo)
{
char cNombreProceso[14]="TP2Client.exe";
char cCadenaLog[100];
SYSTEMTIME localtime;
DWORD dwBytesWritten=0;

    GetLocalTime(&localtime);
	
	sprintf(cCadenaLog,"%02d:%02d:%02d.%03d %s [%d] [%d]: %s : %s \r\n",localtime.wHour, localtime.wMinute,localtime.wSecond,localtime.wMilliseconds,cNombreProceso,GetCurrentProcessId(),iIdHilo,cTipo,cvDetalle);

	if( FALSE == WriteFile(hFile,cCadenaLog,(DWORD)strlen(cCadenaLog),&dwBytesWritten,NULL))
    {
          printf("No puedo escribir en archivo(error %d)\n", GetLastError());
          CloseHandle(hFile);
          return;
    }
	

} 

void usrEliminaFinLinea(char *pcPalabra)
{
	pcPalabra[strlen(pcPalabra)-1]='\0';
}

int usrValidarConfig(char *pcPuntero, int iOpcion)
{
	int iCont,iContIP=0;
	char *cpTokens, cTemp[16]="\0";

	switch(iOpcion)
    {
    case 1:   /*TTL*/
     	for(iCont = 0; pcPuntero[iCont] != '\0'; iCont++)
		{
			if(isdigit(pcPuntero[iCont]))
			++iContIP;
		}
		if ( iContIP == strlen(pcPuntero))
		{
			iCont = atoi(pcPuntero);
			if(iCont > 0 && iCont < 50)    /*TTL de 1 a 50*/
				 return 1;
			else
				 return 0;
		}
		else
		return 0;

	case 2: /*Port*/
		
		for(iCont = 0; pcPuntero[iCont] != '\0'; iCont++)
		{
			if(isdigit(pcPuntero[iCont]))
			++iContIP;
		}
		if (iContIP == strlen(pcPuntero))
		{
			iCont = atoi(pcPuntero);
			if(iCont > 1024 && iCont < 35000)
				return 1;
			else
				return 0;
		}
		else
			return 0;

	case 3: /*IP*/
		strcpy(cTemp,pcPuntero);
        cpTokens = strtok(cTemp,".");
        while(cpTokens !=NULL)
		{
			for(iCont = 0; cpTokens[iCont] != '\0'; iCont++)
			{
				if(!isdigit(cpTokens[iCont]))
					return 0;
				iContIP++;
			}
			if((atoi(cpTokens) < 0)||(atoi(cpTokens)> 255))
                return 0;  
			cpTokens=strtok(NULL,".");
		}

		if (strlen(pcPuntero) == (iContIP+3))
	    	return 1;
		else
	    	return 0;
	}/*fin case*/
	return 0;
}
void usrBorrarBuffer (char *prBuffer)
{
	int iCont=0;
	while (iCont<BUFFER_SIZE)
	{
		prBuffer[iCont]='\0';
		iCont++;
	}
}
int usrLevantoConfiguracion (char *wcArchConf,char *pcIPDestino,char *pcPortDestino, char *pcPortOrigen,char * pcAlmacen)
{
    HANDLE hFile; 
    DWORD dwBytesRead = 0;
    char cReadBuffer[BUFFER_SIZE] = {'\0'};
	char cLinea[BUFFER_SIZE];
	char *pcPuntero;
	char *pcPuntero2;
	char cCreacionDirectorio[40];


	hFile = CreateFileA("ClienteConf.ini",GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NOT_CONTENT_INDEXED,0);                

	if (hFile == INVALID_HANDLE_VALUE) 
    { 
        printf("No se puede abrir archivo (error %d)\n", GetLastError());
		usrGrabarLog ("ERROR","No se puede abrir archivo",hFile,0);
        exit (0);
    }

	if( FALSE == ReadFile(hFile, cReadBuffer,100, &dwBytesRead, NULL) )
	{
		printf("No se puede leer de archivo (error %d)\n", GetLastError());
		usrGrabarLog ("ERROR","No se puede leer archivo",hFile,0);
		CloseHandle(hFile);
		exit (0);
	}



	if( !(strcmp(cReadBuffer,"") == 0))
	{
		strcpy(cLinea,cReadBuffer);
		pcPuntero=strtok(cLinea,"\n");    //Linea IP
		usrEliminaFinLinea(cLinea);
		pcPuntero2=strtok(cLinea,"=");
		if( strcmp(pcPuntero2,"IP") == 0)
		{
			pcPuntero2=strtok(NULL,"=");
			if(usrValidarConfig(pcPuntero2,3))
				strcpy(pcIPDestino,pcPuntero2);
			else
			{
    			printf("IP Invalida\n");
				usrGrabarLog ("ERROR","IP Invalida",hFile,0);
				exit (0);
			}
		}
		strcpy(cLinea,cReadBuffer);
		pcPuntero=strtok(cLinea,"\n");    /*Linea PORT ORIGEN*/
		pcPuntero=strtok(NULL,"\n");
		usrEliminaFinLinea(pcPuntero);
		pcPuntero2=strtok(pcPuntero,"=");
		if( strcmp(pcPuntero2,"PORT-ORIGEN") == 0)
		{
			pcPuntero2=strtok(NULL,"=");
			if(usrValidarConfig(pcPuntero2,2))
				strcpy(pcPortOrigen,pcPuntero2);
			else
			{
		  		printf("PORT Origen Incorrecto\n");
				usrGrabarLog ("ERROR","PORT Origen Incorrecto",hFile,0);
				exit (0);
			}
		}
		strcpy(cLinea,cReadBuffer);
		pcPuntero=strtok(cLinea,"\n");    /*Linea PORT Destino*/
		pcPuntero=strtok(NULL,"\n");
		pcPuntero=strtok(NULL,"\n");
		usrEliminaFinLinea(pcPuntero);
		pcPuntero2=strtok(pcPuntero,"=");
		if( strcmp(pcPuntero2,"PORT-DESTINO") == 0)
		{
			pcPuntero2=strtok(NULL,"=");
			if(usrValidarConfig(pcPuntero2,2))
				strcpy(pcPortDestino,pcPuntero2);
			else
			{
		  		printf("PORT Destino Incorrecto\n");
				usrGrabarLog ("ERROR","PORT Destino Incorrecto",hFile,0);

				exit (0);
			}
		}
	
		strcpy(cLinea,cReadBuffer);
		pcPuntero=strtok(cLinea,"\n");    /*Linea ALMACEN Destino*/
		pcPuntero=strtok(NULL,"\n");
		pcPuntero=strtok(NULL,"\n");
		pcPuntero=strtok(NULL,"\n");
		usrEliminaFinLinea(pcPuntero);
		pcPuntero2=strtok(pcPuntero,"=");
		if( strcmp(pcPuntero2,"ALMACEN") == 0)
		{
			pcPuntero2=strtok(NULL,"=");
			strcpy(pcAlmacen,pcPuntero2);
			sprintf(cCreacionDirectorio,"mkdir %s",pcPuntero2);
			if(GetFileAttributesA(pcPuntero2)==INVALID_FILE_ATTRIBUTES)
			system (cCreacionDirectorio);
		}
	}
	

    CloseHandle(hFile);
	return 0;
}
void usrGotoxy( short x, short y ) 
{ 
    HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE) ; 
    COORD position = { x, y } ; 
     
    SetConsoleCursorPosition( hStdout, position ) ; 
}  
void usrGenerarId (unsigned char  * cDescriptorID)
{
        unsigned int iRandom;
		
        iRandom = rand();
        memcpy( &cDescriptorID[0], &iRandom, 4 );
        iRandom = rand();
		memcpy( &cDescriptorID[4], &iRandom, 4 );
        iRandom = rand();
        memcpy( &cDescriptorID[8], &iRandom, 4 );
        iRandom = rand();
        memcpy( &cDescriptorID[12], &iRandom, 4 );
        return;
}

void usrGrabarEstadisticas ( const char * cArchivo, HANDLE hFileEstadisticas,int iBytes,double stTime,int iModo,int iCantDesc,long stFTPK,long stFTPU,long stFTP)
{

char cCadena[80];
char cCadena2[80];
char cEncabezado[200];
char cCantidadDescargas[80];
char cTiempoFTPKernel[80];
char cTiempoFTPUsuario[80];
char cTiempoFTPTotal[80];
DWORD dwBytesWritten=0;

if (iModo==0)
{
	sprintf(cCadena,"Archivo: %s DatosTX: %d Bytes\r\n",cArchivo,iBytes);

	if( FALSE == WriteFile(hFileEstadisticas,cCadena,(DWORD)strlen(cCadena),&dwBytesWritten,NULL))
	{
		printf("No puedo escribir en archivo estadisticas(error %d)\n", GetLastError());
        CloseHandle(hFileEstadisticas);
        return ;
    }
	sprintf(cCadena2,"Archivo: %s TiempoDescarga: %d Seg\r\n",cArchivo,stTime);

	if( FALSE == WriteFile(hFileEstadisticas,cCadena2,(DWORD)strlen(cCadena2),&dwBytesWritten,NULL))
	{
		printf("No puedo escribir en archivo estadisticas(error %d)\n", GetLastError());
        CloseHandle(hFileEstadisticas);
        return ;
    }
}
else
{
	if (iModo==3)
	{
		strcpy(cEncabezado,"-------------------Estadisticas Cliente v1.01----------------\r\n");

		if( FALSE == WriteFile(hFileEstadisticas,cEncabezado,(DWORD)strlen(cEncabezado),&dwBytesWritten,NULL))
		{
		printf("No puedo escribir en archivo estadisticas(error %d)\r\n", GetLastError());
        CloseHandle(hFileEstadisticas);
        return ;
		}
	}
	else
	{
		sprintf(cCantidadDescargas,"Cantidad de descargas: %d\r\n",iCantDesc);

		if( FALSE == WriteFile(hFileEstadisticas,cCantidadDescargas,(DWORD)strlen(cCantidadDescargas),&dwBytesWritten,NULL))
		{
		printf("No puedo escribir en archivo estadisticas(error %d)\n", GetLastError());
        CloseHandle(hFileEstadisticas);
        return ;
		}
		sprintf(cTiempoFTPUsuario,"Tiempo ejecucion en Modo Usuario: %d Seg\r\n",stFTPU);

		if( FALSE == WriteFile(hFileEstadisticas,cTiempoFTPUsuario,(DWORD)strlen(cTiempoFTPUsuario),&dwBytesWritten,NULL))
		{
		printf("No puedo escribir en archivo estadisticas(error %d)\n", GetLastError());
        CloseHandle(hFileEstadisticas);
        return ;
		}

		sprintf(cTiempoFTPKernel,"Tiempo ejecucion en Modo Kernel: %d Seg\r\n",stFTPK);

		if( FALSE == WriteFile(hFileEstadisticas,cTiempoFTPKernel,(DWORD)strlen(cTiempoFTPKernel),&dwBytesWritten,NULL))
		{
		printf("No puedo escribir en archivo estadisticas(error %d)\n", GetLastError());
        CloseHandle(hFileEstadisticas);
        return ;
		}

		sprintf(cTiempoFTPTotal,"Tiempo Total ejecucion: %d Seg\r\n",stFTP);

		if( FALSE == WriteFile(hFileEstadisticas,cTiempoFTPTotal,(DWORD)strlen(cTiempoFTPTotal),&dwBytesWritten,NULL))
		{
		printf("No puedo escribir en archivo estadisticas(error %d)\n", GetLastError());
        CloseHandle(hFileEstadisticas);
        return ;
		}
	}
	
}
}

void usrInicializarSemaforos (void)
{
	ghSemaphore = CreateSemaphore(NULL,1,1,NULL);	/*Inicializo Semaforo Log*/
    if (ghSemaphore == NULL) 
    {
        printf("CreateSemaforo Log error: %d\n", GetLastError());
		usrGrabarLog ("ERROR","CreateSemaforo Log",hFile,0);
        return;
    }
	ghSemaphoreEst = CreateSemaphore(NULL,1,1,NULL);	/*Inicializo Semaforo Estadisticas*/
    if (ghSemaphore == NULL) 
    {
        printf("CreateSemaforo Estadisticas error: %d\n", GetLastError());
		usrGrabarLog ("ERROR","CreateSemaforo Estadisticas",hFile,0);
        return;
    }
	ghSemaphoreCantDesc = CreateSemaphore(NULL,1,1,NULL);	
    if (ghSemaphore == NULL) 
    {
        printf("CreateSemaforo Cantidad Descargas error: %d\n", GetLastError());
		usrGrabarLog ("ERROR","CreateSemaforo Cantidad Descargas",hFile,0);
        return;
    }
	ghSemaphoreFTPK = CreateSemaphore(NULL,1,1,NULL);
    if (ghSemaphore == NULL) 
    {
        printf("CreateSemaforo FTP Kernel error: %d\n", GetLastError());
		usrGrabarLog ("ERROR","CreateSemaforo FTP Kernel",hFile,0);
        return;
    }
	ghSemaphoreFTPU = CreateSemaphore(NULL,1,1,NULL);	
    if (ghSemaphore == NULL) 
    {
        printf("CreateSemaforo FTP Usuario error: %d\n", GetLastError());
		usrGrabarLog ("ERROR","CreateSemaforo FTP Usuario",hFile,0);
        return;
    }
	ghSemaphoreFTP = CreateSemaphore(NULL,1,1,NULL);	
	if (ghSemaphore == NULL) 
    {
        printf("CreateSemaforo Estadisticas error: %d\n", GetLastError());
		usrGrabarLog ("ERROR","CreateSemaforo Estadisticas",hFile,0);
        return;
    }
}

void usrTiempoInicial(lastCPU, lastSysCPU, lastUserCPU){

	FILETIME ftime, fsys, fuser;
    long qwResultSys,qwResultUser,qwTotal;
    GetSystemTimeAsFileTime(&ftime);
    memcpy(&lastCPU, &ftime, sizeof(FILETIME));
    
    hProc = GetCurrentProcess();
    GetProcessTimes(hProc, &ftime, &ftime, &fsys, &fuser);
	memcpy(&lastSysCPU, &fsys, sizeof(FILETIME));
    memcpy(&lastUserCPU, &fuser, sizeof(FILETIME));
	qwResultSys=lastSysCPU;
	qwResultUser=lastUserCPU;
	qwResultSys=qwResultSys/100000;
	qwResultUser=qwResultUser/100000;
	qwTotal=qwResultSys+qwResultUser;
	WaitForSingleObject( ghSemaphoreEst,INFINITE);	
	usrGrabarEstadisticas ( "",hFileEstadisticas,0,0,2,iCantDesc,qwResultSys,qwResultUser,qwTotal); /*Tiempo FTP Modo Usuario,Kernel,Total,Cantidad Descargas*/
	ReleaseSemaphore(ghSemaphoreEst,1,NULL);


}
double timeval_diff(struct timeval *a, struct timeval *b)
{  
	return  (double)(a->tv_sec + (double)a->tv_usec/1000000) - (double)(b->tv_sec + (double)b->tv_usec/1000000);
}

/*//////////Fin definicion de funciones/////////*/
